//
//  SEGCommonPayViewModel.m
//  SEGViewModel
//
//  Created by 山刘 on 2020/6/15.
//

#import "SEGCommonPayViewModel.h"
#import <WXApiObject.h>
#import "SEGWebViewLoadManager.h"

static int signalCount = 1;

/*
 1. 支付渠道
 2. 支付轮训
 3. 支付后通知
 4. 支付跳转
 */

@interface SEGCommonPayViewModel()
@property (nonatomic, strong, readwrite) RACCommand *confirmPayStatusCommand;
@property (strong, nonatomic, readwrite) RACSubject *messageSubject;
@end

@implementation SEGCommonPayViewModel
#pragma mark - Init
-(instancetype)init{
    if (self = [super init]) {
        [self racInit];
    }
    return self;
}

-(void)dealloc{
    [self.confirmPayStatusCommand rac_deallocDisposable];
    [self.messageSubject rac_deallocDisposable];
}

- (void)racInit{
    
    @weakify(self);
    
    _confirmPayStatusCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(NSDictionary*  _Nullable input) { // input 是 cell的数据
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            @strongify(self);
            
            if (!(input && [input isKindOfClass:[NSDictionary class]] && [[input allKeys] count] > 0)) {
                [self.messageSubject sendNext:@"参数不合法！"];
                return nil;
            }
            
            [self confirmBillPayStatusWithPayMentodInfo:input subscriber:subscriber];
            
            return nil;
        }];
    }];
    
    _appointPayMethodCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        
        @strongify(self);
        
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/uhomecp-app/v1/thirdOrder/payMethodList.json",nil];
            [SEGHTTPBusinessManager seg_requestWithMethod:GET URLString:urlString parameters:nil finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
                
                
                
                if (!isSuccessed) {
                    [self.messageSubject sendNext:errorMessage];
                    [subscriber sendCompleted];
                    return;
                }
                
                NSDictionary *data = [result valueForKey:@"data"];
                NSArray *mentodInfos = [data valueForKey:@"mentodInfos"];
                
                __block NSDictionary *weixiMenthodInfo = [NSDictionary dictionary];
                [mentodInfos enumerateObjectsUsingBlock:^(NSDictionary*  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                    if([[obj valueForKey:@"id"] isEqualToString:@"3"]){
                        weixiMenthodInfo = obj;
                    }
                }];
                
                if ([[weixiMenthodInfo allKeys] count] <= 0) {
                    [self.messageSubject sendNext:@"未开通微信支付！"];
                    [subscriber sendCompleted];
                }
                
                [self confirmBillPayStatusWithPayMentodInfo:weixiMenthodInfo subscriber:subscriber];
            }];
            
            return [RACDisposable disposableWithBlock:^{
            }];
        }];
    }];
    
    _freshUICommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(NSDictionary*  _Nullable input) {
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            @strongify(self);
            
            // 请求支付列表+展示支付列表UI
            if (self.payTypeName == SEGPayTypeName_Group) {
                
                [self.payListRequestModel requestCheckOrderStatusWithOrderId:self.orderIdOracctItemIds finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
                    
                    if (!isSuccessed) {
                        [self.messageSubject sendNext:errorMessage];
                        [subscriber sendCompleted];
                        return;
                    }
                    
                    self.listData = self.payListRequestModel.payMethodList;
                    
                    [subscriber sendNext:nil];
                    [subscriber sendCompleted];
                }];
                
            }else if(self.listData && [self.listData isKindOfClass:[NSArray class]] && self.listData.count > 0){
                [subscriber sendNext:nil];
                [subscriber sendCompleted];
            }
            
            return [RACDisposable disposableWithBlock:^{
            }];
        }];
    }];
}

#pragma mark - 支付工具
-(NSString*)jumpToPayToolsWithChannel:(NSString*)channel params:(NSDictionary*)params {
    
    if (!params) {
        return channel;
    }
    
    if (!(channel && [channel isKindOfClass:[NSString class]] && [channel length] > 0)) {
        channel = [params valueForKey:@"payMethod"];
    }
    
    switch ([channel integerValue]) {
        case 1: // 银联支付
            [self.messageSubject sendNext:@"暂时不支持银联支付！"];
            break;
        case 2: // 支付宝支付
            [self.messageSubject sendNext:@"暂时不支持支付宝支付！"];
            break;
        case 3: // 微信支付
        {
            NSString *tradeString = [params valueForKey:@"trade"];
            
            if (!(tradeString && [tradeString isKindOfClass:[NSString class]] && tradeString.length > 0)) {
                [self.messageSubject sendNext:@"支付失败！"];
            }else{
                NSData *tradeData = [tradeString dataUsingEncoding:NSUTF8StringEncoding];
                NSDictionary *tradeDic = [NSJSONSerialization JSONObjectWithData:tradeData options:0 error:nil];
                
                if (self.payTypeName == SEGPayTypeName_MonthCardPay ||self.payTypeName == SEGPayTypeName_TempCardPay) {
                    
                    /*
                     @"MID":MID,
                     @"OrderNo":OrderNo,
                     @"PayNo":PayNo,
                     @"PayType":PayType,
                     @"PayTime":PayTime,
                     @"Total":Total,
                     */
                    
                    //NSMutableString* stamp = [tradeDic objectForKey:@"timestamp"];
                    // NSMutableDictionary *dicMer = [NSMutableDictionary dictionaryWithDictionary:self.merchantDic];
                    // [dicMer setObject:[dic objectForKey:@"partnerid"] forKey:@"PayNo"];
                    // [dicMer setObject:@"1" forKey:@"PayType"];
                    // [dicMer setObject:[SEGUtils time:stamp Type:SEGSystemUtils_Time_Today_Type_Today_ss] forKey:@"PayTime"];
                    // self.merchantDic = dicMer;
                }
                
                [self toWXPayWithPayReqJsonData:tradeDic];
            }
            
            break;
        }
        case 4: // 货到付款
            //[self.messageSubject sendNext:@"暂时不支持货到付款！"];
            break;
        default:
            break;
    }
    
    return channel;
}

/// 直接发起聚合支付
/// 现在使用的业务场景：SEGPayTypeName_CMHK_PayOnLine
-(void)sendToOnlinePay{
    
    NSDictionary* payInfo = [self.dataDic valueForKey:@"payInfo"];
    NSString* payCode = [self.dataDic valueForKey:@"payCode"];
    
    if ([payCode isEqualToString:@"WEIXIN"]) {
        [self toWXPayWithPayReqJsonData:payInfo];
        return;
    }
    
    [self.messageSubject sendNext:@"暂时不支持此支付方式"];
}

#pragma mark - 微信支付

/// 检查微信状态
-(BOOL)canUseWX{
    
    if (![WXApi isWXAppInstalled]) {
        [self.messageSubject sendNext:kWecharNotInstallTip];
        return NO;
    }
    
    if (![WXApi isWXAppSupportApi]) {
        [self.messageSubject sendNext:@"当前微信的版本不支持OpenApi!"];
        return NO;
    }
    
    return YES;
}

/// 微信支付
/// @param req 参数
-(void)toWXPayWithPayReq:(PayReq*)req{
    
    if (![self canUseWX])  return;
    if (!req) return;
    
    [WXApi sendReq:req completion:nil];
}

/// 微信支付
/// @param params 微信支付参数
-(void)toWXPayWithPayReqJsonData:(NSDictionary*)params{
    
    if (!(params &&
          [params isKindOfClass:[NSDictionary class]] &&
          [[params allKeys] count] > 0)) {
        return;
    }
    
    PayReq* request = [[PayReq alloc] init];
    
    request.partnerId = [params objectForKey:@"partnerid"];
    request.prepayId = [params objectForKey:@"prepayid"];
    request.nonceStr = [params objectForKey:@"noncestr"];
    request.timeStamp = (UInt32)[ValueToString([params objectForKey:@"timestamp"]) intValue];;
    request.package = [params objectForKey:@"package"];
    request.sign = [params objectForKey:@"sign"];
    
    [self toWXPayWithPayReq:request];
}

#pragma mark - 微信小程序支付

/// 微信小程序支付
-(void)toWXMiniProgramPay{
    
    if (![self canUseWX])  return;
    
    WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
    
    launchMiniProgramReq.userName = self.dataDic[@"userName"];  //拉起的小程序的username
    NSString *path = self.dataDic[@"path"];
    //路径需要替换一下参数
    path = [SEGWebViewLoadManager segReplaceUrlStringWithUrlString:path];
    
    NSArray *arr = [path componentsSeparatedByString:@"?"];
    //对path后面的参数进行urlencode 但是&和=号不进行urlencode
    CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding);
    NSString *encoded = (__bridge_transfer NSString *)
    CFURLCreateStringByAddingPercentEscapes(
                                            kCFAllocatorDefault,
                                            (__bridge CFStringRef)arr.lastObject,
                                            NULL,
                                            CFSTR("!#$'()*+,/:;?@[]"),
                                            cfEncoding);//原来为!#$&'()*+,/:;=?@[]

    launchMiniProgramReq.path = [NSString stringWithFormat:@"%@?%@",arr.firstObject,encoded];    ////拉起小程序页面的可带参路径，不填默认拉起小程序首页，对于小游戏，可以只传入 query 部分，来实现传参效果，如：传入 "?foo=bar"。
    
    launchMiniProgramReq.miniProgramType = [self.dataDic[@"miniProgramType"] intValue]; //拉起小程序的类型
    launchMiniProgramReq.extMsg = [self.dataDic yy_modelToJSONString];
    [WXApi sendReq:launchMiniProgramReq completion:nil];
}

#pragma mark - Publish Methods

#pragma mark - Private Methods

/// 轮询查询支付信息
/// @param requestId qingqiuID
-(RACSignal*)retryPollByPaymenetByQuestId:(NSString*)requestId {
    
    signalCount = 1;
    
    return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [[RACScheduler scheduler] afterDelay:1.0 schedule:^{
            [self.payListRequestModel requestPollByPaymenetResultlWithRequestId:requestId finished:^(id result, NSError *error) {
                NSDictionary* resultInfo = result;
                
                if (resultInfo &&
                    [resultInfo isKindOfClass:[NSDictionary class]] &&
                    [[resultInfo objectForKey:@"code"] isEqualToString:@"0"]) {
                    
                    [subscriber sendNext:[resultInfo objectForKey:@"data"]];
                    [subscriber sendCompleted];
                    
                } else {
                    
                    if (signalCount >= 10) {
                        //NSLog(@"sendNext %d",signalCount);
                        [subscriber sendNext:nil];
                        [subscriber sendCompleted];
                    }else {
                        //NSLog(@"sendError %d",signalCount);
                        [subscriber sendError:nil];
                    }
                }
                signalCount++;
            }];
        }];
        
        return nil;
    }];
    
}


/// 把不需要轮询查找支付状态的业务类型放在这里
-(BOOL)noNeedCheckPayOrderStatus{
    if (self.payTypeName == SEGPayTypeName_WashCar ||
        self.payTypeName == SEGPayTypeName_Bill ||
        self.payTypeName == SEGPayTypeName_QiaoChengHui
        ) {
        return YES;
    }
    return NO;
}

/// 拼接确认支付订单状态的入参
/// @param cellDic 点击对应支付方式的数据
-(NSDictionary*)getRequestParamsWithCellDic:(NSDictionary*)cellDic{
    NSMutableDictionary * requestParams = [NSMutableDictionary dictionary];
    
    switch (self.payTypeName) {
        case SEGPayTypeName_Group:{ // 购物
            [requestParams setValue:[SEGServerManager serverUrlJoint:kClientRootURL,@"/uhomecp-app/rest-api/v1/payment/submitOrderPay.json",nil] forKey:@"URL"];
            [requestParams setValue:self.orderIdOracctItemIds forKey:@"orderId"];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            [requestParams setValue:[cellDic objectForKey:@"payeeId"] forKey:@"payeeId"];
            [requestParams setValue:[cellDic objectForKey:@"forwardUrl"] forKey:@"forwardUrl"];
            break;
        }
        case SEGPayTypeName_MonthCard:{ // 月卡缴费提交支付订单，@see:monthCard
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/car-payment-api/rest-api/v1/parkingPayRestApiController/confirmPaymentCharge.json",nil];
            requestParams = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                             [self.dataDic objectForKey:@"cardtype"], @"cardtype",
                             [self.dataDic objectForKey:@"cycleLength"], @"cycleLength",
                             [self.dataDic objectForKey:@"newExpDate"], @"newExpDate",
                             [self.dataDic objectForKey:@"paymentFee"], @"paymentFee",
                             [self.dataDic objectForKey:@"parkingPayField"], @"parkingPayField",
                             [cellDic objectForKey:@"id"], @"payMethod",
                             urlString, @"URL",
                             nil];
            break;
        }
        case SEGPayTypeName_Bill:{ // 账单,self.isBillpay
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/charging-api/rest-api/v3/ysPaymentApiController/getPayConfirmByApp",nil];
            requestParams = [NSMutableDictionary dictionaryWithDictionary:self.dataDic];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            [requestParams setValue:[cellDic objectForKey:@"payeeId"] forKey:@"payeeId"];
            [requestParams setValue:[cellDic objectForKey:@"forwardUrl"] forKey:@"forwardUrl"];
            [requestParams setValue:urlString forKey:@"URL"];
            break;
        }
        case SEGPayTypeName_ServicePay:{ //有偿服务,物业服务提交支付订单-old,isServicePay
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/order-user-api/uhomecp-app/rest-api/v5/order/paid/servicePay.json",nil];
            requestParams = [NSMutableDictionary dictionaryWithDictionary:self.dataDic];
            [requestParams setValue:urlString forKey:@"URL"];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            break;
        }
        case SEGPayTypeName_WashCar:{ //自助洗车,isWashingCar
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/uhomecp-app/flashbox-api/v1/orderPay.json",nil];
            [requestParams setValue:urlString forKey:@"URL"];
            [requestParams setValue:self.orderIdOracctItemIds forKey:@"orderSid"];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            break;
        }
        case SEGPayTypeName_QiaoChengHui:{ // 侨城汇支付，self.payTypeName == SEGPayTypeName_QiaoChengHui
            requestParams = [NSMutableDictionary dictionaryWithDictionary:cellDic];
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/uhomecp-app/v1/thirdOrder/orderPay.json",nil];
            [requestParams setValue:urlString forKey:@"URL"];
            [requestParams setValue:self.orderIdOracctItemIds forKey:@"orderId"];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            [requestParams setValue:kAccountCommunityID forKey:@"communityId"];
            break;
        }
        case SEGPayTypeName_MonthCardPay:{ // 月卡缴费，self.payTypeName == SEGPayTypeName_MonthCardPay
            requestParams = [NSMutableDictionary dictionaryWithDictionary:self.dataDic];
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/uhomecp-app/rest-api/v1/parkingPay/monthCardPaymentNoCalculateCharge.json",nil];
            [requestParams setValue:urlString forKey:@"URL"];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            break;
        }
        case SEGPayTypeName_TempCardPay:{ // 临卡缴费，self.payTypeName == SEGPayTypeName_TempCardPay
            requestParams = [NSMutableDictionary dictionaryWithDictionary:self.dataDic];
            NSString *urlString = [SEGServerManager serverUrlJoint:kClientRootURL,@"/uhomecp-app/rest-api/v1/parkingPay/temporaryCardPaymentNoCalculateCharge.json",nil];
            [requestParams setValue:urlString forKey:@"URL"];
            [requestParams setValue:[cellDic objectForKey:@"id"] forKey:@"payMethod"];
            break;
        }
        default:
            break;
    }
    return [NSDictionary dictionaryWithDictionary:requestParams];
}


-(void)confirmBillPayStatusWithPayMentodInfo:(NSDictionary*)mentodInfo subscriber:(id<RACSubscriber>)subscriber{
    // 根据业务渠道，进行请求参数的拼接
    NSString* payMethod = [mentodInfo valueForKey:@"id"]; // 支付方式
    NSDictionary * requestParams = [self getRequestParamsWithCellDic:mentodInfo];// 请求接口，确定支付订单状态
    
    if ([[requestParams allKeys] count] <= 0) {
        [self.messageSubject sendNext:@"参数错误！"];
        [subscriber sendCompleted];
    }
    
    [self.payListRequestModel requesConfirmBillPayWithDictionary:requestParams finished:^(BOOL isSuccessed, id result, NSString *codeType, NSString *errorMessage) {
        
        if (!isSuccessed) {
            [self.messageSubject sendNext:errorMessage];
            [subscriber sendCompleted];
            return;
        }
        
        // 货到付款
        if ([payMethod isEqualToString:@"4"]) {
            //[self jumpToPayToolsWithChannel:payMethod params:result];
            [subscriber sendNext:@{@"payMethod":payMethod,@"messaage":[result valueForKey:@"message"]}];
            [subscriber sendCompleted];
            return;
        }
        
        // 不需要轮询查看支付订单状态
        if ([self noNeedCheckPayOrderStatus]) {
            [self jumpToPayToolsWithChannel:payMethod params:[result valueForKey:@"data"]];
            [subscriber sendCompleted];
            return;
        }
        
        // 需要轮询查看支付订单状态
        NSString *requestId = [result objectForKey:@"data"];
        RACSignal *pollSignal = [self retryPollByPaymenetByQuestId:requestId];
        
        [[pollSignal retry] subscribeNext:^(id  _Nullable x) {
            
            if (x) [self jumpToPayToolsWithChannel:nil params:x];
            
            //NSLog(@"subscribeNext：%@",x);
            [subscriber sendCompleted];
            
        } error:^(NSError * _Nullable error) {
        }];
        
    }];
}

#pragma mark - Getter
-(RACSubject *)messageSubject{
    if (!_messageSubject) {
        _messageSubject = [RACSubject subject];
    }
    return _messageSubject;
}

- (PayListRequestModel*)payListRequestModel {
    if (!_payListRequestModel) {
        _payListRequestModel = [[PayListRequestModel alloc] init];
    }
    return _payListRequestModel;
}
-(SEGPayTypeName)payTypeName{
    if (!_payTypeName) {
        _payTypeName = SEGPayTypeName_NO;
    }
    return _payTypeName;
}

-(NSArray *)listData{
    if (!_listData) {
        _listData = [NSArray array];
    }
    return _listData;
}

-(SEGDidPaidViewModel *)didPaidViewModel {
    if (!_didPaidViewModel) {
        _didPaidViewModel = [[SEGDidPaidViewModel alloc] init];
    }
    return _didPaidViewModel;
}
#pragma mark - Stter
@end
